package concurrentsandbox;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

@SuppressWarnings("serial")
public class MinWithFJ extends RecursiveAction {
	private final int threshold;
	private final SelectMinProblem problem;
	public int result;

	public MinWithFJ(SelectMinProblem problem, int threshold) {
		this.problem = problem;
		this.threshold = threshold;
	}

	@Override
	protected void compute() {
		if (problem.size < threshold) {
			result = problem.solveSequentially();
        } else {
			int midpoint = problem.size / 2;
			MinWithFJ left = new MinWithFJ(problem.subproblem(0, midpoint),
					threshold);
			MinWithFJ right = new MinWithFJ(problem.subproblem(midpoint + 1,
					problem.size), threshold);
			invokeAll(left, right);
			result = Math.min(left.result, right.result);
		}
	}

	public static int solveUsingFJ(SelectMinProblem problem, int threshold,
			int nThreads) {
		MinWithFJ mfj = new MinWithFJ(problem, threshold);
		ForkJoinPool fjPool = new ForkJoinPool(nThreads);

		fjPool.invoke(mfj);
		int result = mfj.result;
		fjPool.shutdown();
		return result;
	}
}